package com.yupi.springbootinit.bizmq;

import cn.hutool.core.util.StrUtil;
import com.rabbitmq.client.Channel;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.constant.BiMqConstant;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.handler.MyWebSocketHandler;
import com.yupi.springbootinit.manager.AiManager;
import com.yupi.springbootinit.model.entity.Chart;
import com.yupi.springbootinit.model.enums.CharStatusEnum;
import com.yupi.springbootinit.service.ChartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 业务消息消费者
 * @author 穹龙
 * @date 2025/2/10
 */
@Component
@Slf4j
public class BiMessageConsumer {

    @Resource
    private ChartService chartService;
    @Resource
    private AiManager aiManager;
    @Resource
    private MyWebSocketHandler myWebSocketHandler;

    // 指定程序监听的消息队列和确认机制
    @RabbitListener(queues = {BiMqConstant.BI_QUEUE_NAME}, ackMode = "MANUAL")
    public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        try {
            if (StrUtil.isBlank(message)) {
                channel.basicNack(deliveryTag, false, false);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "消息为空");
            }
            log.info("receiveMessage message = {}", message);
            long chartId = Long.parseLong(message);
            Chart chart = chartService.getById(chartId);
            if (chart == null) {
                channel.basicNack(deliveryTag, false, false);
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "图表为空");
            }
            // 先修改任务状态为执行中
            Chart updateChart = new Chart();
            updateChart.setId(chartId);
            updateChart.setStatus(CharStatusEnum.RUNNING.getValue());
            boolean updateSuccess = chartService.updateById(updateChart);
            if (!updateSuccess) {
                this.handleChartUpdateError(chartId, "更新执行状态失败");
                channel.basicNack(deliveryTag, false, false);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "更新执行状态失败");
            }
            String doChat = aiManager.doChat(true, this.buildUserInput(chart));
            String regex = "(?s)(?<=```json)\\s*(.*?)(?=\\s*```)";

            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(doChat);
            if (!matcher.find()) {
                channel.basicNack(deliveryTag, false, false);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "AI 生成格式错误");
            }
            String[] split = doChat.split("结论：");
            if (split.length < 2) {
                channel.basicNack(deliveryTag, false, false);
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "AI 生成错误");
            }
            String genChart = matcher.group().trim();
            String genResult = "结论：" + split[1].trim();
            Chart updateChartResult = new Chart();
            updateChartResult.setId(chart.getId());
            updateChartResult.setGenChart(genChart);
            updateChartResult.setGenResult(genResult);
            updateChartResult.setStatus(CharStatusEnum.SUCCEED.getValue());
            boolean updateResultSuccess = chartService.updateById(updateChartResult);
            if (!updateResultSuccess) {
                this.handleChartUpdateError(chart.getId(), "更新图表结果失败");
                channel.basicNack(deliveryTag, false, false);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "更新图表结果失败");
            }
            // 确认
            channel.basicAck(deliveryTag, false);
            // 处理完成发送完成消息
            myWebSocketHandler.sendMessageByUserId(chart.getUserId().toString(), chart.getChartName() + "已生成完成");
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, e.getMessage());
        }
    }

    // 构建用户输入
    private String buildUserInput(Chart chart) {
        String goal = chart.getGoal();
        String chartType = chart.getChartType();
        String csvData = chart.getChartData();

        StringBuilder userInput = new StringBuilder();
        userInput.append("分析需求：").append("\n");
        String userGoal = goal + "，请使用" + chartType;
        userInput.append(userGoal).append("\n");
        userInput.append("原始数据：").append(csvData).append("\n");
        return userInput.toString();
    }

    private void handleChartUpdateError(Long chartId, String execMessage) {
        Chart updateChart = new Chart();
        updateChart.setId(chartId);
        updateChart.setStatus(CharStatusEnum.FAILED.getValue());
        updateChart.setExecMessage(execMessage);
        chartService.updateById(updateChart);
    }
}
